{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第5阶段 第3讲：可视化综合项目\n",
    "\n",
    "**课程时长**: 1小时  \n",
    "**难度等级**: ⭐⭐⭐⭐⭐\n",
    "\n",
    "---\n",
    "\n",
    "## 📚 本讲学习目标\n",
    "\n",
    "1. 掌握企业级仪表板的完整开发流程\n",
    "2. 学会数据故事讲述(Data Storytelling)的技巧\n",
    "3. 理解仪表板设计的最佳实践\n",
    "4. 能够独立完成从需求到部署的全流程\n",
    "5. 掌握多数据源集成和实时更新技术\n",
    "\n",
    "---\n",
    "\n",
    "## 🎯 项目背景\n",
    "\n",
    "### 场景描述\n",
    "\n",
    "**公司**: 某全国连锁零售企业  \n",
    "**部门**: 数据分析部  \n",
    "**需求方**: 销售总监、运营总监  \n",
    "\n",
    "**业务痛点**:\n",
    "- 📊 数据分散在多个Excel文件中,难以整合\n",
    "- ⏰ 每周需要人工制作报表,耗时3-4小时\n",
    "- 🔍 管理层无法实时了解业务状况\n",
    "- 📈 缺乏趋势预警和异常检测机制\n",
    "\n",
    "**项目目标**:\n",
    "构建一个企业级销售运营仪表板,实现:\n",
    "1. 实时数据监控\n",
    "2. 多维度分析能力\n",
    "3. 自动化报表生成\n",
    "4. 移动端友好访问\n",
    "\n",
    "---\n",
    "\n",
    "## 📊 Excel vs Python 企业级仪表板对比\n",
    "\n",
    "| 对比维度 | Excel仪表板 | Python仪表板(Streamlit) |\n",
    "|---------|------------|------------------------|\n",
    "| 开发时间 | 2-3天(手工设置) | 1-2天(代码自动化) |\n",
    "| 实时性 | 需手动刷新 | 自动实时更新 |\n",
    "| 数据容量 | <100万行(性能下降) | 千万级数据无压力 |\n",
    "| 交互性 | 有限(切片器) | 丰富(多种交互组件) |\n",
    "| 多用户访问 | 文件共享(版本混乱) | Web应用(统一版本) |\n",
    "| 移动端 | 体验差 | 完美适配 |\n",
    "| 自动化 | 需VBA编程 | Python全自动化 |\n",
    "| 维护成本 | 高(手工修改) | 低(代码维护) |\n",
    "| 扩展性 | 差(Excel限制) | 强(无限扩展) |\n",
    "| 成本 | Office订阅 | 开源免费 |\n",
    "\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1️⃣ 项目规划与设计\n",
    "\n",
    "### 1.1 需求分析\n",
    "\n",
    "**功能需求**:\n",
    "\n",
    "| 功能模块 | 具体需求 | 优先级 |\n",
    "|---------|---------|-------|\n",
    "| 概览页 | KPI指标、趋势图、预警信息 | P0 |\n",
    "| 销售分析 | 地区/产品/时间维度分析 | P0 |\n",
    "| 客户分析 | 客户画像、RFM分析 | P1 |\n",
    "| 库存分析 | 库存周转、滞销预警 | P1 |\n",
    "| 数据导出 | 支持PDF/Excel导出 | P2 |\n",
    "| 权限管理 | 不同角色看不同数据 | P2 |\n",
    "\n",
    "**非功能需求**:\n",
    "- 响应时间 < 2秒\n",
    "- 支持100+并发用户\n",
    "- 数据刷新频率: 每小时\n",
    "- 移动端适配"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2 信息架构设计\n",
    "\n",
    "```\n",
    "销售运营仪表板\n",
    "│\n",
    "├── 📊 概览页 (Overview)\n",
    "│   ├── 核心KPI (销售额、订单量、客单价、利润率)\n",
    "│   ├── 趋势图 (本月 vs 上月)\n",
    "│   ├── 预警信息 (异常指标)\n",
    "│   └── 快速洞察 (Top产品、Top地区)\n",
    "│\n",
    "├── 📈 销售分析 (Sales)\n",
    "│   ├── 时间维度 (日/周/月/季度/年)\n",
    "│   ├── 地区维度 (华东、华南、华北等)\n",
    "│   ├── 产品维度 (类别、品牌、SKU)\n",
    "│   └── 渠道维度 (线上、线下、经销商)\n",
    "│\n",
    "├── 👥 客户分析 (Customer)\n",
    "│   ├── 客户分层 (新客、活跃、流失)\n",
    "│   ├── RFM模型 (最近、频率、金额)\n",
    "│   ├── 客户画像 (年龄、性别、地域)\n",
    "│   └── 复购分析\n",
    "│\n",
    "├── 📦 库存分析 (Inventory)\n",
    "│   ├── 库存状态 (充足、预警、缺货)\n",
    "│   ├── 周转率分析\n",
    "│   ├── 滞销品识别\n",
    "│   └── 补货建议\n",
    "│\n",
    "└── ⚙️ 设置 (Settings)\n",
    "    ├── 数据刷新\n",
    "    ├── 筛选器配置\n",
    "    └── 报表导出\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.3 数据故事设计\n",
    "\n",
    "**优秀仪表板的3个层次**:\n",
    "\n",
    "1. **What (是什么)** - 展示数据\n",
    "   - KPI指标卡片\n",
    "   - 基础图表\n",
    "\n",
    "2. **So What (意味着什么)** - 解释数据\n",
    "   - 同比/环比变化\n",
    "   - 趋势分析\n",
    "   - 异常标注\n",
    "\n",
    "3. **Now What (该做什么)** - 行动建议\n",
    "   - 预警提示\n",
    "   - 优化建议\n",
    "   - 下一步行动\n",
    "\n",
    "**示例: 销售下降的故事讲述**\n",
    "\n",
    "```\n",
    "❌ 差的展示:\n",
    "\"本月销售额: ¥5,000,000\"\n",
    "\n",
    "✅ 好的故事:\n",
    "\"本月销售额: ¥5,000,000 ⬇️ 下降15%\n",
    " 主要原因: 华南地区下降30%(受台风影响)\n",
    " 建议行动: \n",
    "  1. 加大华东地区促销力度补偿损失\n",
    "  2. 华南地区准备灾后重建营销方案\n",
    "  3. 预计下月可恢复正常水平\"\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## 2️⃣ 数据准备\n",
    "\n",
    "### 2.1 生成模拟企业数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入必要的库\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import plotly.express as px\n",
    "import plotly.graph_objects as go\n",
    "from plotly.subplots import make_subplots\n",
    "from datetime import datetime, timedelta\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "print(\"✅ 库导入成功!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 设置随机种子\n",
    "np.random.seed(42)\n",
    "\n",
    "# 生成2年的销售数据\n",
    "start_date = datetime(2023, 1, 1)\n",
    "end_date = datetime(2024, 12, 31)\n",
    "date_range = pd.date_range(start_date, end_date, freq='D')\n",
    "\n",
    "# 定义维度数据\n",
    "regions = ['华东', '华南', '华北', '西南', '东北']\n",
    "categories = ['电子产品', '服装鞋帽', '食品饮料', '家居用品', '图书文具']\n",
    "channels = ['线上', '线下', '经销商']\n",
    "customer_types = ['新客户', '老客户']\n",
    "\n",
    "# 生成订单数据\n",
    "n_records = 50000  # 5万条订单记录\n",
    "\n",
    "orders_data = pd.DataFrame({\n",
    "    '订单ID': [f'ORD{str(i).zfill(8)}' for i in range(1, n_records + 1)],\n",
    "    '订单日期': np.random.choice(date_range, n_records),\n",
    "    '地区': np.random.choice(regions, n_records, p=[0.3, 0.25, 0.2, 0.15, 0.1]),\n",
    "    '产品类别': np.random.choice(categories, n_records),\n",
    "    '渠道': np.random.choice(channels, n_records, p=[0.5, 0.3, 0.2]),\n",
    "    '客户类型': np.random.choice(customer_types, n_records, p=[0.3, 0.7]),\n",
    "    '数量': np.random.randint(1, 10, n_records),\n",
    "    '单价': np.random.uniform(50, 500, n_records),\n",
    "})\n",
    "\n",
    "# 计算销售额和成本\n",
    "orders_data['销售额'] = orders_data['数量'] * orders_data['单价']\n",
    "orders_data['成本'] = orders_data['销售额'] * np.random.uniform(0.5, 0.7, n_records)\n",
    "orders_data['利润'] = orders_data['销售额'] - orders_data['成本']\n",
    "orders_data['利润率'] = orders_data['利润'] / orders_data['销售额'] * 100\n",
    "\n",
    "# 添加客户ID\n",
    "orders_data['客户ID'] = [f'CUST{np.random.randint(1, 10000):05d}' for _ in range(n_records)]\n",
    "\n",
    "# 添加产品名称\n",
    "product_templates = {\n",
    "    '电子产品': ['手机', '平板', '耳机', '充电器', '数据线'],\n",
    "    '服装鞋帽': ['T恤', '牛仔裤', '运动鞋', '衬衫', '外套'],\n",
    "    '食品饮料': ['零食', '饮料', '方便面', '饼干', '巧克力'],\n",
    "    '家居用品': ['水杯', '毛巾', '拖鞋', '收纳盒', '衣架'],\n",
    "    '图书文具': ['笔记本', '签字笔', '书籍', '便签', '文件夹']\n",
    "}\n",
    "\n",
    "orders_data['产品名称'] = orders_data['产品类别'].apply(\n",
    "    lambda x: np.random.choice(product_templates[x])\n",
    ")\n",
    "\n",
    "print(f\"✅ 生成了 {len(orders_data):,} 条订单记录\")\n",
    "print(f\"📅 时间范围: {orders_data['订单日期'].min()} 至 {orders_data['订单日期'].max()}\")\n",
    "print(f\"💰 总销售额: ¥{orders_data['销售额'].sum():,.0f}\")\n",
    "print(f\"📊 数据维度: {orders_data.shape[1]} 列\")\n",
    "\n",
    "orders_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 生成客户数据\n",
    "unique_customers = orders_data['客户ID'].unique()\n",
    "\n",
    "customer_data = pd.DataFrame({\n",
    "    '客户ID': unique_customers,\n",
    "    '客户姓名': [f'客户{i}' for i in range(len(unique_customers))],\n",
    "    '性别': np.random.choice(['男', '女'], len(unique_customers)),\n",
    "    '年龄': np.random.randint(18, 65, len(unique_customers)),\n",
    "    '注册日期': [start_date + timedelta(days=np.random.randint(0, 365*2)) \n",
    "                 for _ in range(len(unique_customers))],\n",
    "    '会员等级': np.random.choice(['普通', '银卡', '金卡', '钻石'], \n",
    "                               len(unique_customers), \n",
    "                               p=[0.5, 0.3, 0.15, 0.05])\n",
    "})\n",
    "\n",
    "print(f\"✅ 生成了 {len(customer_data):,} 个客户档案\")\n",
    "customer_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 生成库存数据\n",
    "n_products = 200\n",
    "\n",
    "all_products = []\n",
    "for category, products in product_templates.items():\n",
    "    for product in products:\n",
    "        for region in regions:\n",
    "            all_products.append({\n",
    "                '产品类别': category,\n",
    "                '产品名称': product,\n",
    "                '地区': region,\n",
    "                '当前库存': np.random.randint(0, 1000),\n",
    "                '安全库存': np.random.randint(100, 300)\n",
    "            })\n",
    "\n",
    "inventory_data = pd.DataFrame(all_products)\n",
    "inventory_data['SKU'] = [f'SKU{i:05d}' for i in range(len(inventory_data))]\n",
    "inventory_data['库存状态'] = inventory_data.apply(\n",
    "    lambda x: '缺货' if x['当前库存'] == 0 \n",
    "    else '预警' if x['当前库存'] < x['安全库存'] \n",
    "    else '正常', \n",
    "    axis=1\n",
    ")\n",
    "\n",
    "print(f\"✅ 生成了 {len(inventory_data):,} 个SKU的库存数据\")\n",
    "print(f\"\\n库存状态分布:\")\n",
    "print(inventory_data['库存状态'].value_counts())\n",
    "\n",
    "inventory_data.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2 数据预处理和特征工程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 添加时间维度字段\n",
    "orders_data['年份'] = orders_data['订单日期'].dt.year\n",
    "orders_data['季度'] = orders_data['订单日期'].dt.quarter\n",
    "orders_data['月份'] = orders_data['订单日期'].dt.month\n",
    "orders_data['周'] = orders_data['订单日期'].dt.isocalendar().week\n",
    "orders_data['星期'] = orders_data['订单日期'].dt.dayofweek\n",
    "orders_data['年月'] = orders_data['订单日期'].dt.to_period('M').astype(str)\n",
    "\n",
    "# 添加星期名称\n",
    "weekday_map = {0: '周一', 1: '周二', 2: '周三', 3: '周四', 4: '周五', 5: '周六', 6: '周日'}\n",
    "orders_data['星期名称'] = orders_data['星期'].map(weekday_map)\n",
    "\n",
    "print(\"✅ 时间维度字段添加完成\")\n",
    "print(\"\\n新增字段:\")\n",
    "print(orders_data[['订单日期', '年份', '季度', '月份', '周', '星期名称', '年月']].head(3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算RFM指标\n",
    "analysis_date = orders_data['订单日期'].max() + timedelta(days=1)\n",
    "\n",
    "rfm_data = orders_data.groupby('客户ID').agg({\n",
    "    '订单日期': lambda x: (analysis_date - x.max()).days,  # Recency\n",
    "    '订单ID': 'count',  # Frequency\n",
    "    '销售额': 'sum'  # Monetary\n",
    "}).reset_index()\n",
    "\n",
    "rfm_data.columns = ['客户ID', 'R_最近购买天数', 'F_购买频次', 'M_总消费金额']\n",
    "\n",
    "# RFM评分(1-5分,5分最好)\n",
    "rfm_data['R_评分'] = pd.qcut(rfm_data['R_最近购买天数'], 5, labels=[5, 4, 3, 2, 1], duplicates='drop')\n",
    "rfm_data['F_评分'] = pd.qcut(rfm_data['F_购买频次'].rank(method='first'), 5, labels=[1, 2, 3, 4, 5], duplicates='drop')\n",
    "rfm_data['M_评分'] = pd.qcut(rfm_data['M_总消费金额'].rank(method='first'), 5, labels=[1, 2, 3, 4, 5], duplicates='drop')\n",
    "\n",
    "rfm_data['RFM_综合评分'] = (\n",
    "    rfm_data['R_评分'].astype(int) + \n",
    "    rfm_data['F_评分'].astype(int) + \n",
    "    rfm_data['M_评分'].astype(int)\n",
    ")\n",
    "\n",
    "# 客户分层\n",
    "def classify_customer(score):\n",
    "    if score >= 13:\n",
    "        return '💎 高价值客户'\n",
    "    elif score >= 10:\n",
    "        return '🥇 重要保持客户'\n",
    "    elif score >= 7:\n",
    "        return '🥈 潜力客户'\n",
    "    else:\n",
    "        return '🥉 一般客户'\n",
    "\n",
    "rfm_data['客户分层'] = rfm_data['RFM_综合评分'].apply(classify_customer)\n",
    "\n",
    "print(\"✅ RFM分析完成\")\n",
    "print(\"\\n客户分层分布:\")\n",
    "print(rfm_data['客户分层'].value_counts())\n",
    "\n",
    "rfm_data.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## 3️⃣ 核心可视化组件开发\n",
    "\n",
    "### 3.1 KPI指标卡片组件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def calculate_kpis(df, current_period, previous_period):\n",
    "    \"\"\"\n",
    "    计算KPI指标及同比变化\n",
    "    \n",
    "    参数:\n",
    "        df: 订单数据\n",
    "        current_period: 当前期间的数据\n",
    "        previous_period: 对比期间的数据\n",
    "    \n",
    "    返回:\n",
    "        dict: KPI指标字典\n",
    "    \"\"\"\n",
    "    kpis = {}\n",
    "    \n",
    "    # 销售额\n",
    "    current_sales = current_period['销售额'].sum()\n",
    "    previous_sales = previous_period['销售额'].sum()\n",
    "    sales_change = (current_sales - previous_sales) / previous_sales * 100 if previous_sales > 0 else 0\n",
    "    \n",
    "    kpis['销售额'] = {\n",
    "        '当前值': current_sales,\n",
    "        '对比值': previous_sales,\n",
    "        '变化率': sales_change\n",
    "    }\n",
    "    \n",
    "    # 订单量\n",
    "    current_orders = len(current_period)\n",
    "    previous_orders = len(previous_period)\n",
    "    orders_change = (current_orders - previous_orders) / previous_orders * 100 if previous_orders > 0 else 0\n",
    "    \n",
    "    kpis['订单量'] = {\n",
    "        '当前值': current_orders,\n",
    "        '对比值': previous_orders,\n",
    "        '变化率': orders_change\n",
    "    }\n",
    "    \n",
    "    # 客单价\n",
    "    current_avg = current_sales / current_orders if current_orders > 0 else 0\n",
    "    previous_avg = previous_sales / previous_orders if previous_orders > 0 else 0\n",
    "    avg_change = (current_avg - previous_avg) / previous_avg * 100 if previous_avg > 0 else 0\n",
    "    \n",
    "    kpis['客单价'] = {\n",
    "        '当前值': current_avg,\n",
    "        '对比值': previous_avg,\n",
    "        '变化率': avg_change\n",
    "    }\n",
    "    \n",
    "    # 利润率\n",
    "    current_profit_rate = current_period['利润率'].mean()\n",
    "    previous_profit_rate = previous_period['利润率'].mean()\n",
    "    profit_rate_change = current_profit_rate - previous_profit_rate\n",
    "    \n",
    "    kpis['利润率'] = {\n",
    "        '当前值': current_profit_rate,\n",
    "        '对比值': previous_profit_rate,\n",
    "        '变化率': profit_rate_change\n",
    "    }\n",
    "    \n",
    "    return kpis\n",
    "\n",
    "# 测试KPI计算\n",
    "current_month = orders_data[orders_data['年月'] == '2024-12']\n",
    "previous_month = orders_data[orders_data['年月'] == '2024-11']\n",
    "\n",
    "kpis = calculate_kpis(orders_data, current_month, previous_month)\n",
    "\n",
    "print(\"📊 2024年12月 KPI指标:\")\n",
    "print(\"=\"*60)\n",
    "for metric, values in kpis.items():\n",
    "    if metric == '利润率':\n",
    "        print(f\"{metric}: {values['当前值']:.2f}% (环比 {values['变化率']:+.2f}个百分点)\")\n",
    "    elif metric == '客单价':\n",
    "        print(f\"{metric}: ¥{values['当前值']:,.0f} (环比 {values['变化率']:+.1f}%)\")\n",
    "    elif metric == '销售额':\n",
    "        print(f\"{metric}: ¥{values['当前值']:,.0f} (环比 {values['变化率']:+.1f}%)\")\n",
    "    else:\n",
    "        print(f\"{metric}: {values['当前值']:,} (环比 {values['变化率']:+.1f}%)\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2 趋势分析图表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 月度销售趋势\n",
    "monthly_sales = orders_data.groupby('年月').agg({\n",
    "    '销售额': 'sum',\n",
    "    '订单ID': 'count',\n",
    "    '利润': 'sum'\n",
    "}).reset_index()\n",
    "\n",
    "monthly_sales.columns = ['年月', '销售额', '订单量', '利润']\n",
    "monthly_sales['客单价'] = monthly_sales['销售额'] / monthly_sales['订单量']\n",
    "\n",
    "# 创建双Y轴图表\n",
    "fig = make_subplots(\n",
    "    rows=1, cols=1,\n",
    "    specs=[[{'secondary_y': True}]]\n",
    ")\n",
    "\n",
    "# 添加销售额柱状图\n",
    "fig.add_trace(\n",
    "    go.Bar(\n",
    "        x=monthly_sales['年月'],\n",
    "        y=monthly_sales['销售额'],\n",
    "        name='销售额',\n",
    "        marker_color='lightblue',\n",
    "        hovertemplate='<b>%{x}</b><br>销售额: ¥%{y:,.0f}<extra></extra>'\n",
    "    ),\n",
    "    secondary_y=False\n",
    ")\n",
    "\n",
    "# 添加订单量折线图\n",
    "fig.add_trace(\n",
    "    go.Scatter(\n",
    "        x=monthly_sales['年月'],\n",
    "        y=monthly_sales['订单量'],\n",
    "        name='订单量',\n",
    "        mode='lines+markers',\n",
    "        line=dict(color='red', width=3),\n",
    "        marker=dict(size=8),\n",
    "        hovertemplate='<b>%{x}</b><br>订单量: %{y:,}<extra></extra>'\n",
    "    ),\n",
    "    secondary_y=True\n",
    ")\n",
    "\n",
    "# 更新布局\n",
    "fig.update_layout(\n",
    "    title='📈 月度销售趋势分析(2023-2024)',\n",
    "    template='plotly_white',\n",
    "    hovermode='x unified',\n",
    "    height=450,\n",
    "    legend=dict(orientation='h', yanchor='bottom', y=1.02, xanchor='right', x=1)\n",
    ")\n",
    "\n",
    "fig.update_xaxes(title_text='月份')\n",
    "fig.update_yaxes(title_text='销售额(元)', secondary_y=False)\n",
    "fig.update_yaxes(title_text='订单量', secondary_y=True)\n",
    "\n",
    "fig.show()\n",
    "\n",
    "# 数据洞察\n",
    "max_sales_month = monthly_sales.loc[monthly_sales['销售额'].idxmax()]\n",
    "min_sales_month = monthly_sales.loc[monthly_sales['销售额'].idxmin()]\n",
    "avg_monthly_sales = monthly_sales['销售额'].mean()\n",
    "\n",
    "print(\"\\n💡 趋势洞察:\")\n",
    "print(f\"  • 销售最高月份: {max_sales_month['年月']} (¥{max_sales_month['销售额']:,.0f})\")\n",
    "print(f\"  • 销售最低月份: {min_sales_month['年月']} (¥{min_sales_month['销售额']:,.0f})\")\n",
    "print(f\"  • 月均销售额: ¥{avg_monthly_sales:,.0f}\")\n",
    "print(f\"  • 销售波动率: {monthly_sales['销售额'].std() / avg_monthly_sales * 100:.1f}%\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.3 多维度对比分析"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建2x2子图进行多维度对比\n",
    "fig = make_subplots(\n",
    "    rows=2, cols=2,\n",
    "    subplot_titles=(\n",
    "        '地区销售额分布',\n",
    "        '产品类别销售占比',\n",
    "        '渠道销售对比',\n",
    "        '客户类型分析'\n",
    "    ),\n",
    "    specs=[\n",
    "        [{'type': 'bar'}, {'type': 'pie'}],\n",
    "        [{'type': 'bar'}, {'type': 'bar'}]\n",
    "    ],\n",
    "    vertical_spacing=0.12,\n",
    "    horizontal_spacing=0.1\n",
    ")\n",
    "\n",
    "# 1. 地区销售额\n",
    "region_sales = orders_data.groupby('地区')['销售额'].sum().sort_values(ascending=True)\n",
    "fig.add_trace(\n",
    "    go.Bar(\n",
    "        x=region_sales.values,\n",
    "        y=region_sales.index,\n",
    "        orientation='h',\n",
    "        marker_color='lightblue',\n",
    "        text=region_sales.values,\n",
    "        texttemplate='¥%{text:,.0f}',\n",
    "        textposition='outside',\n",
    "        showlegend=False\n",
    "    ),\n",
    "    row=1, col=1\n",
    ")\n",
    "\n",
    "# 2. 产品类别占比\n",
    "category_sales = orders_data.groupby('产品类别')['销售额'].sum()\n",
    "fig.add_trace(\n",
    "    go.Pie(\n",
    "        labels=category_sales.index,\n",
    "        values=category_sales.values,\n",
    "        hole=0.3,\n",
    "        showlegend=True\n",
    "    ),\n",
    "    row=1, col=2\n",
    ")\n",
    "\n",
    "# 3. 渠道销售对比\n",
    "channel_sales = orders_data.groupby('渠道')['销售额'].sum().sort_values(ascending=False)\n",
    "fig.add_trace(\n",
    "    go.Bar(\n",
    "        x=channel_sales.index,\n",
    "        y=channel_sales.values,\n",
    "        marker_color=['#FF6B6B', '#4ECDC4', '#45B7D1'],\n",
    "        text=channel_sales.values,\n",
    "        texttemplate='¥%{text:,.0f}',\n",
    "        textposition='outside',\n",
    "        showlegend=False\n",
    "    ),\n",
    "    row=2, col=1\n",
    ")\n",
    "\n",
    "# 4. 客户类型分析\n",
    "customer_stats = orders_data.groupby('客户类型').agg({\n",
    "    '销售额': 'sum',\n",
    "    '订单ID': 'count'\n",
    "}).reset_index()\n",
    "\n",
    "fig.add_trace(\n",
    "    go.Bar(\n",
    "        x=customer_stats['客户类型'],\n",
    "        y=customer_stats['销售额'],\n",
    "        marker_color=['#95E1D3', '#F38181'],\n",
    "        text=customer_stats['销售额'],\n",
    "        texttemplate='¥%{text:,.0f}',\n",
    "        textposition='outside',\n",
    "        showlegend=False\n",
    "    ),\n",
    "    row=2, col=2\n",
    ")\n",
    "\n",
    "# 更新布局\n",
    "fig.update_layout(\n",
    "    title_text='📊 多维度销售分析仪表板',\n",
    "    template='plotly_white',\n",
    "    height=700,\n",
    "    showlegend=True\n",
    ")\n",
    "\n",
    "# 更新坐标轴标题\n",
    "fig.update_xaxes(title_text='销售额(元)', row=1, col=1)\n",
    "fig.update_xaxes(title_text='渠道', row=2, col=1)\n",
    "fig.update_xaxes(title_text='客户类型', row=2, col=2)\n",
    "\n",
    "fig.update_yaxes(title_text='地区', row=1, col=1)\n",
    "fig.update_yaxes(title_text='销售额(元)', row=2, col=1)\n",
    "fig.update_yaxes(title_text='销售额(元)', row=2, col=2)\n",
    "\n",
    "fig.show()\n",
    "\n",
    "print(\"\\n📊 多维度分析摘要:\")\n",
    "print(f\"  • 销售最高地区: {region_sales.idxmax()} (¥{region_sales.max():,.0f})\")\n",
    "print(f\"  • 销售最高类别: {category_sales.idxmax()} (占比 {category_sales.max()/category_sales.sum()*100:.1f}%)\")\n",
    "print(f\"  • 销售最高渠道: {channel_sales.idxmax()} (¥{channel_sales.max():,.0f})\")\n",
    "print(f\"  • 老客户贡献: {customer_stats[customer_stats['客户类型']=='老客户']['销售额'].values[0] / customer_stats['销售额'].sum() * 100:.1f}%\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.4 客户RFM分析可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# RFM 3D散点图\n",
    "fig = px.scatter_3d(\n",
    "    rfm_data.head(500),  # 取前500个客户避免过度拥挤\n",
    "    x='R_最近购买天数',\n",
    "    y='F_购买频次',\n",
    "    z='M_总消费金额',\n",
    "    color='客户分层',\n",
    "    size='M_总消费金额',\n",
    "    hover_data=['客户ID', 'RFM_综合评分'],\n",
    "    title='🎯 客户RFM三维分析(前500名客户)',\n",
    "    color_discrete_map={\n",
    "        '💎 高价值客户': '#FFD700',\n",
    "        '🥇 重要保持客户': '#C0C0C0',\n",
    "        '🥈 潜力客户': '#CD7F32',\n",
    "        '🥉 一般客户': '#A9A9A9'\n",
    "    },\n",
    "    size_max=20\n",
    ")\n",
    "\n",
    "fig.update_layout(\n",
    "    scene=dict(\n",
    "        xaxis_title='最近购买天数(越小越好)',\n",
    "        yaxis_title='购买频次(越大越好)',\n",
    "        zaxis_title='总消费金额(越大越好)'\n",
    "    ),\n",
    "    height=600\n",
    ")\n",
    "\n",
    "fig.show()\n",
    "\n",
    "# 客户分层统计\n",
    "print(\"\\n👥 客户分层详细统计:\")\n",
    "print(\"=\"*80)\n",
    "\n",
    "segment_stats = rfm_data.groupby('客户分层').agg({\n",
    "    '客户ID': 'count',\n",
    "    'M_总消费金额': 'sum',\n",
    "    'F_购买频次': 'mean',\n",
    "    'R_最近购买天数': 'mean'\n",
    "}).round(1)\n",
    "\n",
    "segment_stats.columns = ['客户数量', '总消费金额', '平均购买频次', '平均最近购买天数']\n",
    "segment_stats['占比'] = (segment_stats['客户数量'] / segment_stats['客户数量'].sum() * 100).round(1)\n",
    "segment_stats['贡献度'] = (segment_stats['总消费金额'] / segment_stats['总消费金额'].sum() * 100).round(1)\n",
    "\n",
    "# 按总消费金额降序排列\n",
    "segment_stats = segment_stats.sort_values('总消费金额', ascending=False)\n",
    "\n",
    "print(segment_stats)\n",
    "\n",
    "print(\"\\n💡 客户洞察:\")\n",
    "print(f\"  • 高价值客户占比 {segment_stats.loc['💎 高价值客户', '占比']:.1f}%,但贡献了 {segment_stats.loc['💎 高价值客户', '贡献度']:.1f}% 的销售额\")\n",
    "print(f\"  • 一般客户占比 {segment_stats.loc['🥉 一般客户', '占比']:.1f}%,需要重点激活\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.5 库存预警仪表板"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 库存状态分布\n",
    "inventory_summary = inventory_data.groupby('库存状态').agg({\n",
    "    'SKU': 'count',\n",
    "    '当前库存': 'sum'\n",
    "}).reset_index()\n",
    "\n",
    "inventory_summary.columns = ['库存状态', 'SKU数量', '总库存量']\n",
    "\n",
    "# 创建子图\n",
    "fig = make_subplots(\n",
    "    rows=1, cols=2,\n",
    "    subplot_titles=('库存状态分布', '各地区库存预警情况'),\n",
    "    specs=[[{'type': 'pie'}, {'type': 'bar'}]]\n",
    ")\n",
    "\n",
    "# 库存状态饼图\n",
    "colors = {'正常': '#28a745', '预警': '#ffc107', '缺货': '#dc3545'}\n",
    "pie_colors = [colors.get(status, '#6c757d') for status in inventory_summary['库存状态']]\n",
    "\n",
    "fig.add_trace(\n",
    "    go.Pie(\n",
    "        labels=inventory_summary['库存状态'],\n",
    "        values=inventory_summary['SKU数量'],\n",
    "        marker=dict(colors=pie_colors),\n",
    "        textposition='inside',\n",
    "        textinfo='percent+label'\n",
    "    ),\n",
    "    row=1, col=1\n",
    ")\n",
    "\n",
    "# 各地区预警情况\n",
    "region_warning = inventory_data[inventory_data['库存状态'].isin(['预警', '缺货'])].groupby('地区').size().sort_values(ascending=True)\n",
    "\n",
    "fig.add_trace(\n",
    "    go.Bar(\n",
    "        x=region_warning.values,\n",
    "        y=region_warning.index,\n",
    "        orientation='h',\n",
    "        marker_color='#dc3545',\n",
    "        text=region_warning.values,\n",
    "        textposition='outside',\n",
    "        showlegend=False\n",
    "    ),\n",
    "    row=1, col=2\n",
    ")\n",
    "\n",
    "fig.update_layout(\n",
    "    title_text='📦 库存状态监控仪表板',\n",
    "    template='plotly_white',\n",
    "    height=400,\n",
    "    showlegend=False\n",
    ")\n",
    "\n",
    "fig.update_xaxes(title_text='预警SKU数量', row=1, col=2)\n",
    "fig.update_yaxes(title_text='地区', row=1, col=2)\n",
    "\n",
    "fig.show()\n",
    "\n",
    "# 库存预警详情\n",
    "print(\"\\n⚠️ 库存预警详情:\")\n",
    "print(\"=\"*80)\n",
    "\n",
    "warning_items = inventory_data[inventory_data['库存状态'] != '正常'].sort_values('当前库存')\n",
    "\n",
    "print(f\"\\n总计 {len(warning_items)} 个SKU需要关注:\")\n",
    "print(f\"  • 缺货: {len(inventory_data[inventory_data['库存状态']=='缺货'])} 个SKU\")\n",
    "print(f\"  • 预警: {len(inventory_data[inventory_data['库存状态']=='预警'])} 个SKU\")\n",
    "\n",
    "print(\"\\n前10个最紧急的SKU:\")\n",
    "print(warning_items[['SKU', '产品类别', '产品名称', '地区', '当前库存', '安全库存', '库存状态']].head(10))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## 4️⃣ 完整Streamlit仪表板应用\n",
    "\n",
    "### 4.1 完整代码实现\n",
    "\n",
    "将以下代码保存为 `enterprise_dashboard.py`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "enterprise_dashboard_code = '''\n",
    "import streamlit as st\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import plotly.express as px\n",
    "import plotly.graph_objects as go\n",
    "from plotly.subplots import make_subplots\n",
    "from datetime import datetime, timedelta\n",
    "import io\n",
    "\n",
    "# ================================\n",
    "# 页面配置\n",
    "# ================================\n",
    "st.set_page_config(\n",
    "    page_title=\"企业销售运营仪表板\",\n",
    "    page_icon=\"📊\",\n",
    "    layout=\"wide\",\n",
    "    initial_sidebar_state=\"expanded\"\n",
    ")\n",
    "\n",
    "# 自定义CSS\n",
    "st.markdown(\"\"\"\n",
    "    <style>\n",
    "    .main-header {\n",
    "        font-size: 36px;\n",
    "        font-weight: bold;\n",
    "        color: #1f77b4;\n",
    "        text-align: center;\n",
    "        margin-bottom: 10px;\n",
    "    }\n",
    "    .sub-header {\n",
    "        font-size: 18px;\n",
    "        color: #666;\n",
    "        text-align: center;\n",
    "        margin-bottom: 30px;\n",
    "    }\n",
    "    .metric-container {\n",
    "        background-color: #f0f2f6;\n",
    "        padding: 15px;\n",
    "        border-radius: 10px;\n",
    "        box-shadow: 2px 2px 5px rgba(0,0,0,0.1);\n",
    "    }\n",
    "    .warning-box {\n",
    "        background-color: #fff3cd;\n",
    "        border-left: 5px solid #ffc107;\n",
    "        padding: 10px;\n",
    "        margin: 10px 0;\n",
    "    }\n",
    "    .danger-box {\n",
    "        background-color: #f8d7da;\n",
    "        border-left: 5px solid #dc3545;\n",
    "        padding: 10px;\n",
    "        margin: 10px 0;\n",
    "    }\n",
    "    .success-box {\n",
    "        background-color: #d4edda;\n",
    "        border-left: 5px solid #28a745;\n",
    "        padding: 10px;\n",
    "        margin: 10px 0;\n",
    "    }\n",
    "    </style>\n",
    "\"\"\", unsafe_allow_html=True)\n",
    "\n",
    "# ================================\n",
    "# 数据加载函数\n",
    "# ================================\n",
    "@st.cache_data\n",
    "def load_data():\n",
    "    \"\"\"加载和生成示例数据\"\"\"\n",
    "    np.random.seed(42)\n",
    "    \n",
    "    # 生成订单数据\n",
    "    start_date = datetime(2023, 1, 1)\n",
    "    end_date = datetime(2024, 12, 31)\n",
    "    date_range = pd.date_range(start_date, end_date, freq=\\'D\\')\n",
    "    \n",
    "    regions = [\\'华东\\', \\'华南\\', \\'华北\\', \\'西南\\', \\'东北\\']\n",
    "    categories = [\\'电子产品\\', \\'服装鞋帽\\', \\'食品饮料\\', \\'家居用品\\', \\'图书文具\\']\n",
    "    channels = [\\'线上\\', \\'线下\\', \\'经销商\\']\n",
    "    customer_types = [\\'新客户\\', \\'老客户\\']\n",
    "    \n",
    "    n_records = 50000\n",
    "    \n",
    "    orders = pd.DataFrame({\n",
    "        \\'订单ID\\': [f\\'ORD{str(i).zfill(8)}\\' for i in range(1, n_records + 1)],\n",
    "        \\'订单日期\\': np.random.choice(date_range, n_records),\n",
    "        \\'地区\\': np.random.choice(regions, n_records, p=[0.3, 0.25, 0.2, 0.15, 0.1]),\n",
    "        \\'产品类别\\': np.random.choice(categories, n_records),\n",
    "        \\'渠道\\': np.random.choice(channels, n_records, p=[0.5, 0.3, 0.2]),\n",
    "        \\'客户类型\\': np.random.choice(customer_types, n_records, p=[0.3, 0.7]),\n",
    "        \\'数量\\': np.random.randint(1, 10, n_records),\n",
    "        \\'单价\\': np.random.uniform(50, 500, n_records),\n",
    "    })\n",
    "    \n",
    "    orders[\\'销售额\\'] = orders[\\'数量\\'] * orders[\\'单价\\']\n",
    "    orders[\\'成本\\'] = orders[\\'销售额\\'] * np.random.uniform(0.5, 0.7, n_records)\n",
    "    orders[\\'利润\\'] = orders[\\'销售额\\'] - orders[\\'成本\\']\n",
    "    orders[\\'利润率\\'] = orders[\\'利润\\'] / orders[\\'销售额\\'] * 100\n",
    "    \n",
    "    # 时间字段\n",
    "    orders[\\'年份\\'] = orders[\\'订单日期\\'].dt.year\n",
    "    orders[\\'季度\\'] = orders[\\'订单日期\\'].dt.quarter\n",
    "    orders[\\'月份\\'] = orders[\\'订单日期\\'].dt.month\n",
    "    orders[\\'年月\\'] = orders[\\'订单日期\\'].dt.to_period(\\'M\\').astype(str)\n",
    "    \n",
    "    return orders\n",
    "\n",
    "@st.cache_data\n",
    "def calculate_rfm(orders):\n",
    "    \"\"\"计算RFM指标\"\"\"\n",
    "    # 为每个订单分配客户ID\n",
    "    orders[\\'客户ID\\'] = [f\\'CUST{np.random.randint(1, 10000):05d}\\' for _ in range(len(orders))]\n",
    "    \n",
    "    analysis_date = orders[\\'订单日期\\'].max() + timedelta(days=1)\n",
    "    \n",
    "    rfm = orders.groupby(\\'客户ID\\').agg({\n",
    "        \\'订单日期\\': lambda x: (analysis_date - x.max()).days,\n",
    "        \\'订单ID\\': \\'count\\',\n",
    "        \\'销售额\\': \\'sum\\'\n",
    "    }).reset_index()\n",
    "    \n",
    "    rfm.columns = [\\'客户ID\\', \\'R_最近购买天数\\', \\'F_购买频次\\', \\'M_总消费金额\\']\n",
    "    \n",
    "    # RFM评分\n",
    "    rfm[\\'R_评分\\'] = pd.qcut(rfm[\\'R_最近购买天数\\'], 5, labels=[5, 4, 3, 2, 1], duplicates=\\'drop\\')\n",
    "    rfm[\\'F_评分\\'] = pd.qcut(rfm[\\'F_购买频次\\'].rank(method=\\'first\\'), 5, labels=[1, 2, 3, 4, 5], duplicates=\\'drop\\')\n",
    "    rfm[\\'M_评分\\'] = pd.qcut(rfm[\\'M_总消费金额\\'].rank(method=\\'first\\'), 5, labels=[1, 2, 3, 4, 5], duplicates=\\'drop\\')\n",
    "    \n",
    "    rfm[\\'RFM_综合评分\\'] = rfm[\\'R_评分\\'].astype(int) + rfm[\\'F_评分\\'].astype(int) + rfm[\\'M_评分\\'].astype(int)\n",
    "    \n",
    "    def classify_customer(score):\n",
    "        if score >= 13:\n",
    "            return \\'💎 高价值客户\\'\n",
    "        elif score >= 10:\n",
    "            return \\'🥇 重要保持客户\\'\n",
    "        elif score >= 7:\n",
    "            return \\'🥈 潜力客户\\'\n",
    "        else:\n",
    "            return \\'🥉 一般客户\\'\n",
    "    \n",
    "    rfm[\\'客户分层\\'] = rfm[\\'RFM_综合评分\\'].apply(classify_customer)\n",
    "    \n",
    "    return rfm\n",
    "\n",
    "# ================================\n",
    "# 加载数据\n",
    "# ================================\n",
    "with st.spinner(\\'正在加载数据...\\'):\n",
    "    orders_data = load_data()\n",
    "    rfm_data = calculate_rfm(orders_data)\n",
    "\n",
    "# ================================\n",
    "# 页面标题\n",
    "# ================================\n",
    "st.markdown(\\'<p class=\"main-header\">📊 企业销售运营仪表板</p>\\', unsafe_allow_html=True)\n",
    "st.markdown(\\'<p class=\"sub-header\">实时数据监控 · 智能决策支持 · 业务洞察分析</p>\\', unsafe_allow_html=True)\n",
    "st.markdown(\\'---\\')\n",
    "\n",
    "# ================================\n",
    "# 侧边栏 - 筛选器\n",
    "# ================================\n",
    "st.sidebar.header(\\'🔍 数据筛选器\\')\n",
    "\n",
    "# 日期范围\n",
    "date_range = st.sidebar.date_input(\n",
    "    \\'选择日期范围\\',\n",
    "    value=(orders_data[\\'订单日期\\'].min(), orders_data[\\'订单日期\\'].max()),\n",
    "    min_value=orders_data[\\'订单日期\\'].min(),\n",
    "    max_value=orders_data[\\'订单日期\\'].max()\n",
    ")\n",
    "\n",
    "# 地区筛选\n",
    "regions = st.sidebar.multiselect(\n",
    "    \\'选择地区\\',\n",
    "    options=orders_data[\\'地区\\'].unique(),\n",
    "    default=orders_data[\\'地区\\'].unique()\n",
    ")\n",
    "\n",
    "# 产品类别\n",
    "categories = st.sidebar.multiselect(\n",
    "    \\'选择产品类别\\',\n",
    "    options=orders_data[\\'产品类别\\'].unique(),\n",
    "    default=orders_data[\\'产品类别\\'].unique()\n",
    ")\n",
    "\n",
    "# 渠道\n",
    "channels = st.sidebar.multiselect(\n",
    "    \\'选择销售渠道\\',\n",
    "    options=orders_data[\\'渠道\\'].unique(),\n",
    "    default=orders_data[\\'渠道\\'].unique()\n",
    ")\n",
    "\n",
    "# 应用筛选\n",
    "if len(date_range) == 2:\n",
    "    start_date, end_date = date_range\n",
    "    filtered_data = orders_data[\n",
    "        (orders_data[\\'订单日期\\'] >= pd.Timestamp(start_date)) &\n",
    "        (orders_data[\\'订单日期\\'] <= pd.Timestamp(end_date)) &\n",
    "        (orders_data[\\'地区\\'].isin(regions)) &\n",
    "        (orders_data[\\'产品类别\\'].isin(categories)) &\n",
    "        (orders_data[\\'渠道\\'].isin(channels))\n",
    "    ]\n",
    "else:\n",
    "    filtered_data = orders_data[\n",
    "        (orders_data[\\'地区\\'].isin(regions)) &\n",
    "        (orders_data[\\'产品类别\\'].isin(categories)) &\n",
    "        (orders_data[\\'渠道\\'].isin(channels))\n",
    "    ]\n",
    "\n",
    "st.sidebar.markdown(\\'---\\')\n",
    "st.sidebar.subheader(\\'📊 数据统计\\')\n",
    "st.sidebar.write(f\\'总订单数: {len(filtered_data):,}\\')\n",
    "st.sidebar.write(f\\'筛选占比: {len(filtered_data)/len(orders_data)*100:.1f}%\\')\n",
    "\n",
    "# ================================\n",
    "# 主面板 - 选项卡导航\n",
    "# ================================\n",
    "tab1, tab2, tab3, tab4 = st.tabs([\n",
    "    \\'📊 业务概览\\',\n",
    "    \\'📈 销售分析\\',\n",
    "    \\'👥 客户分析\\',\n",
    "    \\'📋 数据导出\\'\n",
    "])\n",
    "\n",
    "# ================================\n",
    "# Tab 1: 业务概览\n",
    "# ================================\n",
    "with tab1:\n",
    "    st.subheader(\\'🎯 核心业务指标\\')\n",
    "    \n",
    "    # KPI指标\n",
    "    col1, col2, col3, col4, col5 = st.columns(5)\n",
    "    \n",
    "    total_sales = filtered_data[\\'销售额\\'].sum()\n",
    "    total_orders = len(filtered_data)\n",
    "    avg_order_value = total_sales / total_orders if total_orders > 0 else 0\n",
    "    total_profit = filtered_data[\\'利润\\'].sum()\n",
    "    avg_profit_rate = filtered_data[\\'利润率\\'].mean()\n",
    "    \n",
    "    with col1:\n",
    "        st.metric(\n",
    "            label=\\'总销售额\\',\n",
    "            value=f\\'¥{total_sales:,.0f}\\',\n",
    "            delta=f\\'{total_sales/orders_data[\"销售额\"].sum()*100:.1f}%\\'\n",
    "        )\n",
    "    \n",
    "    with col2:\n",
    "        st.metric(\n",
    "            label=\\'订单量\\',\n",
    "            value=f\\'{total_orders:,}\\',\n",
    "            delta=f\\'{total_orders/len(orders_data)*100:.1f}%\\'\n",
    "        )\n",
    "    \n",
    "    with col3:\n",
    "        st.metric(\n",
    "            label=\\'客单价\\',\n",
    "            value=f\\'¥{avg_order_value:.0f}\\'\n",
    "        )\n",
    "    \n",
    "    with col4:\n",
    "        st.metric(\n",
    "            label=\\'总利润\\',\n",
    "            value=f\\'¥{total_profit:,.0f}\\'\n",
    "        )\n",
    "    \n",
    "    with col5:\n",
    "        st.metric(\n",
    "            label=\\'平均利润率\\',\n",
    "            value=f\\'{avg_profit_rate:.1f}%\\'\n",
    "        )\n",
    "    \n",
    "    st.markdown(\\'---\\')\n",
    "    \n",
    "    # 趋势图\n",
    "    col_left, col_right = st.columns(2)\n",
    "    \n",
    "    with col_left:\n",
    "        st.subheader(\\'📈 销售趋势\\')\n",
    "        monthly_sales = filtered_data.groupby(\\'年月\\')[\\'销售额\\'].sum().reset_index()\n",
    "        fig_trend = px.line(\n",
    "            monthly_sales,\n",
    "            x=\\'年月\\',\n",
    "            y=\\'销售额\\',\n",
    "            title=\\'月度销售额趋势\\'\n",
    "        )\n",
    "        fig_trend.update_traces(line_color=\\'#1f77b4\\', line_width=3)\n",
    "        fig_trend.update_layout(template=\\'plotly_white\\', height=350)\n",
    "        st.plotly_chart(fig_trend, use_container_width=True)\n",
    "    \n",
    "    with col_right:\n",
    "        st.subheader(\\'🗺️ 地区分布\\')\n",
    "        region_sales = filtered_data.groupby(\\'地区\\')[\\'销售额\\'].sum().reset_index()\n",
    "        fig_region = px.pie(\n",
    "            region_sales,\n",
    "            values=\\'销售额\\',\n",
    "            names=\\'地区\\',\n",
    "            title=\\'各地区销售额占比\\',\n",
    "            hole=0.4\n",
    "        )\n",
    "        fig_region.update_layout(height=350)\n",
    "        st.plotly_chart(fig_region, use_container_width=True)\n",
    "    \n",
    "    # 智能洞察\n",
    "    st.markdown(\\'---\\')\n",
    "    st.subheader(\\'💡 智能洞察\\')\n",
    "    \n",
    "    # 找出表现最好的维度\n",
    "    top_region = filtered_data.groupby(\\'地区\\')[\\'销售额\\'].sum().idxmax()\n",
    "    top_category = filtered_data.groupby(\\'产品类别\\')[\\'销售额\\'].sum().idxmax()\n",
    "    top_channel = filtered_data.groupby(\\'渠道\\')[\\'销售额\\'].sum().idxmax()\n",
    "    \n",
    "    col_insight1, col_insight2, col_insight3 = st.columns(3)\n",
    "    \n",
    "    with col_insight1:\n",
    "        st.markdown(f\\'<div class=\"success-box\">🏆 <b>销售冠军地区</b><br>{top_region}</div>\\', unsafe_allow_html=True)\n",
    "    \n",
    "    with col_insight2:\n",
    "        st.markdown(f\\'<div class=\"success-box\">🛒 <b>热销产品类别</b><br>{top_category}</div>\\', unsafe_allow_html=True)\n",
    "    \n",
    "    with col_insight3:\n",
    "        st.markdown(f\\'<div class=\"success-box\">📡 <b>最佳销售渠道</b><br>{top_channel}</div>\\', unsafe_allow_html=True)\n",
    "\n",
    "# ================================\n",
    "# Tab 2: 销售分析\n",
    "# ================================\n",
    "with tab2:\n",
    "    st.subheader(\\'📊 多维度销售分析\\')\n",
    "    \n",
    "    analysis_dimension = st.radio(\n",
    "        \\'选择分析维度\\',\n",
    "        [\\'地区\\', \\'产品类别\\', \\'渠道\\', \\'客户类型\\'],\n",
    "        horizontal=True\n",
    "    )\n",
    "    \n",
    "    # 按选择的维度聚合\n",
    "    dimension_sales = filtered_data.groupby(analysis_dimension).agg({\n",
    "        \\'销售额\\': \\'sum\\',\n",
    "        \\'订单ID\\': \\'count\\',\n",
    "        \\'利润\\': \\'sum\\'\n",
    "    }).reset_index()\n",
    "    \n",
    "    dimension_sales.columns = [analysis_dimension, \\'销售额\\', \\'订单量\\', \\'利润\\']\n",
    "    dimension_sales[\\'客单价\\'] = dimension_sales[\\'销售额\\'] / dimension_sales[\\'订单量\\']\n",
    "    dimension_sales = dimension_sales.sort_values(\\'销售额\\', ascending=False)\n",
    "    \n",
    "    col_chart, col_table = st.columns([2, 1])\n",
    "    \n",
    "    with col_chart:\n",
    "        fig_bar = px.bar(\n",
    "            dimension_sales,\n",
    "            x=analysis_dimension,\n",
    "            y=\\'销售额\\',\n",
    "            color=\\'销售额\\',\n",
    "            title=f\\'{analysis_dimension}销售额对比\\',\n",
    "            text=\\'销售额\\',\n",
    "            color_continuous_scale=\\'Blues\\'\n",
    "        )\n",
    "        fig_bar.update_traces(texttemplate=\\'¥%{text:,.0f}\\', textposition=\\'outside\\')\n",
    "        fig_bar.update_layout(template=\\'plotly_white\\', height=400, showlegend=False)\n",
    "        st.plotly_chart(fig_bar, use_container_width=True)\n",
    "    \n",
    "    with col_table:\n",
    "        st.dataframe(\n",
    "            dimension_sales.style.format({\n",
    "                \\'销售额\\': \\'¥{:,.0f}\\',\n",
    "                \\'订单量\\': \\'{:,}\\',\n",
    "                \\'利润\\': \\'¥{:,.0f}\\',\n",
    "                \\'客单价\\': \\'¥{:.0f}\\'\n",
    "            }),\n",
    "            height=400,\n",
    "            use_container_width=True\n",
    "        )\n",
    "    \n",
    "    st.markdown(\\'---\\')\n",
    "    \n",
    "    # 时间序列分析\n",
    "    st.subheader(\\'📅 时间序列分析\\')\n",
    "    \n",
    "    time_granularity = st.selectbox(\n",
    "        \\'选择时间粒度\\',\n",
    "        [\\'年月\\', \\'季度\\', \\'年份\\']\n",
    "    )\n",
    "    \n",
    "    if time_granularity == \\'季度\\':\n",
    "        filtered_data[\\'时间维度\\'] = filtered_data[\\'年份\\'].astype(str) + \\'Q\\' + filtered_data[\\'季度\\'].astype(str)\n",
    "    elif time_granularity == \\'年份\\':\n",
    "        filtered_data[\\'时间维度\\'] = filtered_data[\\'年份\\'].astype(str)\n",
    "    else:\n",
    "        filtered_data[\\'时间维度\\'] = filtered_data[\\'年月\\']\n",
    "    \n",
    "    time_series = filtered_data.groupby(\\'时间维度\\').agg({\n",
    "        \\'销售额\\': \\'sum\\',\n",
    "        \\'订单ID\\': \\'count\\'\n",
    "    }).reset_index()\n",
    "    \n",
    "    time_series.columns = [\\'时间\\', \\'销售额\\', \\'订单量\\']\n",
    "    \n",
    "    fig_time = make_subplots(specs=[[{\\'secondary_y\\': True}]])\n",
    "    \n",
    "    fig_time.add_trace(\n",
    "        go.Bar(x=time_series[\\'时间\\'], y=time_series[\\'销售额\\'], name=\\'销售额\\', marker_color=\\'lightblue\\'),\n",
    "        secondary_y=False\n",
    "    )\n",
    "    \n",
    "    fig_time.add_trace(\n",
    "        go.Scatter(x=time_series[\\'时间\\'], y=time_series[\\'订单量\\'], name=\\'订单量\\', mode=\\'lines+markers\\', line=dict(color=\\'red\\', width=3)),\n",
    "        secondary_y=True\n",
    "    )\n",
    "    \n",
    "    fig_time.update_layout(\n",
    "        title=f\\'{time_granularity}销售趋势\\',\n",
    "        template=\\'plotly_white\\',\n",
    "        hovermode=\\'x unified\\',\n",
    "        height=400\n",
    "    )\n",
    "    \n",
    "    fig_time.update_yaxes(title_text=\\'销售额(元)\\', secondary_y=False)\n",
    "    fig_time.update_yaxes(title_text=\\'订单量\\', secondary_y=True)\n",
    "    \n",
    "    st.plotly_chart(fig_time, use_container_width=True)\n",
    "\n",
    "# ================================\n",
    "# Tab 3: 客户分析\n",
    "# ================================\n",
    "with tab3:\n",
    "    st.subheader(\\'👥 客户价值分析(RFM)\\')\n",
    "    \n",
    "    # 客户分层统计\n",
    "    segment_stats = rfm_data.groupby(\\'客户分层\\').agg({\n",
    "        \\'客户ID\\': \\'count\\',\n",
    "        \\'M_总消费金额\\': \\'sum\\'\n",
    "    }).reset_index()\n",
    "    \n",
    "    segment_stats.columns = [\\'客户分层\\', \\'客户数量\\', \\'总消费金额\\']\n",
    "    segment_stats[\\'占比\\'] = segment_stats[\\'客户数量\\'] / segment_stats[\\'客户数量\\'].sum() * 100\n",
    "    segment_stats[\\'贡献度\\'] = segment_stats[\\'总消费金额\\'] / segment_stats[\\'总消费金额\\'].sum() * 100\n",
    "    segment_stats = segment_stats.sort_values(\\'总消费金额\\', ascending=False)\n",
    "    \n",
    "    col_pie, col_bar = st.columns(2)\n",
    "    \n",
    "    with col_pie:\n",
    "        fig_segment_pie = px.pie(\n",
    "            segment_stats,\n",
    "            values=\\'客户数量\\',\n",
    "            names=\\'客户分层\\',\n",
    "            title=\\'客户分层分布\\',\n",
    "            hole=0.4\n",
    "        )\n",
    "        fig_segment_pie.update_layout(height=350)\n",
    "        st.plotly_chart(fig_segment_pie, use_container_width=True)\n",
    "    \n",
    "    with col_bar:\n",
    "        fig_contribution = px.bar(\n",
    "            segment_stats,\n",
    "            x=\\'客户分层\\',\n",
    "            y=\\'贡献度\\',\n",
    "            title=\\'各层级销售额贡献度\\',\n",
    "            text=\\'贡献度\\'\n",
    "        )\n",
    "        fig_contribution.update_traces(texttemplate=\\'%{text:.1f}%\\', textposition=\\'outside\\')\n",
    "        fig_contribution.update_layout(template=\\'plotly_white\\', height=350)\n",
    "        st.plotly_chart(fig_contribution, use_container_width=True)\n",
    "    \n",
    "    st.markdown(\\'---\\')\n",
    "    \n",
    "    # RFM详细数据\n",
    "    st.subheader(\\'📋 客户分层详细数据\\')\n",
    "    \n",
    "    st.dataframe(\n",
    "        segment_stats.style.format({\n",
    "            \\'客户数量\\': \\'{:,}\\',\n",
    "            \\'总消费金额\\': \\'¥{:,.0f}\\',\n",
    "            \\'占比\\': \\'{:.1f}%\\',\n",
    "            \\'贡献度\\': \\'{:.1f}%\\'\n",
    "        }),\n",
    "        use_container_width=True\n",
    "    )\n",
    "    \n",
    "    # 营销建议\n",
    "    st.markdown(\\'---\\')\n",
    "    st.subheader(\\'💡 营销策略建议\\')\n",
    "    \n",
    "    col_s1, col_s2 = st.columns(2)\n",
    "    \n",
    "    with col_s1:\n",
    "        st.markdown(\\'<div class=\"success-box\"><b>💎 高价值客户</b><br>• VIP专属服务<br>• 优先新品体验<br>• 积分翻倍奖励</div>\\', unsafe_allow_html=True)\n",
    "        st.markdown(\\'<div class=\"warning-box\"><b>🥈 潜力客户</b><br>• 定向优惠券<br>• 限时促销活动<br>• 会员升级引导</div>\\', unsafe_allow_html=True)\n",
    "    \n",
    "    with col_s2:\n",
    "        st.markdown(\\'<div class=\"success-box\"><b>🥇 重要保持客户</b><br>• 定期关怀回访<br>• 生日专属福利<br>• 推荐奖励计划</div>\\', unsafe_allow_html=True)\n",
    "        st.markdown(\\'<div class=\"danger-box\"><b>🥉 一般客户</b><br>• 激活唤醒活动<br>• 新人专享优惠<br>• 兴趣推荐营销</div>\\', unsafe_allow_html=True)\n",
    "\n",
    "# ================================\n",
    "# Tab 4: 数据导出\n",
    "# ================================\n",
    "with tab4:\n",
    "    st.subheader(\\'📥 数据导出\\')\n",
    "    \n",
    "    col_export1, col_export2 = st.columns(2)\n",
    "    \n",
    "    with col_export1:\n",
    "        st.write(\\'**导出筛选后的订单数据**\\')\n",
    "        csv = filtered_data.to_csv(index=False, encoding=\\'utf-8-sig\\')\n",
    "        st.download_button(\n",
    "            label=\\'📊 下载订单数据(CSV)\\',\n",
    "            data=csv,\n",
    "            file_name=f\\'orders_{datetime.now().strftime(\"%Y%m%d_%H%M%S\")}.csv\\',\n",
    "            mime=\\'text/csv\\'\n",
    "        )\n",
    "    \n",
    "    with col_export2:\n",
    "        st.write(\\'**导出RFM分析数据**\\')\n",
    "        rfm_csv = rfm_data.to_csv(index=False, encoding=\\'utf-8-sig\\')\n",
    "        st.download_button(\n",
    "            label=\\'👥 下载客户RFM数据(CSV)\\',\n",
    "            data=rfm_csv,\n",
    "            file_name=f\\'rfm_{datetime.now().strftime(\"%Y%m%d_%H%M%S\")}.csv\\',\n",
    "            mime=\\'text/csv\\'\n",
    "        )\n",
    "    \n",
    "    st.markdown(\\'---\\')\n",
    "    \n",
    "    # 数据预览\n",
    "    st.subheader(\\'👀 数据预览\\')\n",
    "    \n",
    "    preview_option = st.radio(\n",
    "        \\'选择预览数据\\',\n",
    "        [\\'订单数据\\', \\'RFM数据\\'],\n",
    "        horizontal=True\n",
    "    )\n",
    "    \n",
    "    if preview_option == \\'订单数据\\':\n",
    "        st.dataframe(\n",
    "            filtered_data.head(100),\n",
    "            use_container_width=True,\n",
    "            height=400\n",
    "        )\n",
    "    else:\n",
    "        st.dataframe(\n",
    "            rfm_data.head(100),\n",
    "            use_container_width=True,\n",
    "            height=400\n",
    "        )\n",
    "\n",
    "# ================================\n",
    "# 页脚\n",
    "# ================================\n",
    "st.markdown(\\'---\\')\n",
    "st.markdown(\n",
    "    f\\'<div style=\"text-align: center; color: gray;\">\\'\n",
    "    f\\'📊 企业销售运营仪表板 v1.0 | 数据更新时间: {datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")} | \\'\n",
    "    f\\'总数据量: {len(orders_data):,}条订单\\'\n",
    "    f\\'</div>\\',\n",
    "    unsafe_allow_html=True\n",
    ")\n",
    "'''\n",
    "\n",
    "print(\"✅ 企业级仪表板完整代码已生成!\")\n",
    "print(\"\\n📦 代码特性:\")\n",
    "print(\"  ✓ 4个功能模块(概览、销售、客户、导出)\")\n",
    "print(\"  ✓ 多维度数据筛选\")\n",
    "print(\"  ✓ 15+ 交互式图表\")\n",
    "print(\"  ✓ RFM客户价值分析\")\n",
    "print(\"  ✓ 智能营销建议\")\n",
    "print(\"  ✓ 数据导出功能\")\n",
    "print(\"  ✓ 响应式布局\")\n",
    "print(\"  ✓ 自定义CSS样式\")\n",
    "print(\"\\n💾 使用方法:\")\n",
    "print(\"  1. 将代码保存为 enterprise_dashboard.py\")\n",
    "print(\"  2. 运行: streamlit run enterprise_dashboard.py\")\n",
    "print(\"  3. 浏览器自动打开应用\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## 5️⃣ 仪表板最佳实践\n",
    "\n",
    "### 5.1 设计原则\n",
    "\n",
    "**1. 信息层次(Information Hierarchy)**\n",
    "\n",
    "```\n",
    "优先级1: KPI指标 (最醒目位置,大字体)\n",
    "  ├─ 核心业务指标\n",
    "  └─ 同比/环比变化\n",
    "\n",
    "优先级2: 趋势图表 (占据主要视觉空间)\n",
    "  ├─ 时间序列趋势\n",
    "  └─ 关键维度对比\n",
    "\n",
    "优先级3: 详细分析 (折叠或下方)\n",
    "  ├─ 明细数据表格\n",
    "  └─ 深度分析图表\n",
    "```\n",
    "\n",
    "**2. 5秒法则**\n",
    "\n",
    "用户应该在5秒内理解:\n",
    "- ✅ 这个仪表板是关于什么的\n",
    "- ✅ 当前业务状况(好/坏)\n",
    "- ✅ 需要关注的关键问题\n",
    "\n",
    "**3. 色彩语言**\n",
    "\n",
    "- 🟢 绿色: 正向、达标、增长\n",
    "- 🔴 红色: 负向、预警、下降\n",
    "- 🟡 黄色: 中性、待观察\n",
    "- 🔵 蓝色: 中性数据展示\n",
    "\n",
    "**4. 留白原则**\n",
    "\n",
    "```\n",
    "❌ 糟糕的设计:\n",
    "[图表][图表][图表][图表]\n",
    "[图表][图表][图表][图表]\n",
    "[图表][图表][图表][图表]\n",
    "\n",
    "✅ 优秀的设计:\n",
    "[   重点图表   ]\n",
    "\n",
    "[图表] [图表]\n",
    "\n",
    "[  详细数据  ]\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5.2 性能优化清单\n",
    "\n",
    "| 优化项 | 优化前 | 优化后 | 方法 |\n",
    "|-------|-------|-------|------|\n",
    "| 数据加载 | 每次重新读取 | 缓存加载 | @st.cache_data |\n",
    "| 图表渲染 | 全量数据 | 采样/聚合 | 超过1万条数据采样展示 |\n",
    "| 计算密集型 | 每次重算 | 缓存结果 | @st.cache_data |\n",
    "| 大文件上传 | 内存加载 | 分块读取 | pd.read_csv(chunksize) |\n",
    "| 实时刷新 | 手动刷新 | 定时刷新 | st.experimental_rerun() |\n",
    "\n",
    "**代码示例**:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "performance_tips = '''\n",
    "# 1. 数据采样展示\n",
    "if len(data) > 10000:\n",
    "    display_data = data.sample(10000)\n",
    "else:\n",
    "    display_data = data\n",
    "\n",
    "# 2. 聚合后再可视化\n",
    "# ❌ 不好的做法\n",
    "fig = px.scatter(raw_data, x='date', y='value')  # 100万个点\n",
    "\n",
    "# ✅ 好的做法\n",
    "daily_data = raw_data.groupby('date')['value'].mean().reset_index()\n",
    "fig = px.line(daily_data, x='date', y='value')  # 只有365个点\n",
    "\n",
    "# 3. 延迟加载\n",
    "with st.expander(\"查看详细数据\"):\n",
    "    # 只有用户点击时才加载详细数据\n",
    "    detailed_data = load_detailed_data()\n",
    "    st.dataframe(detailed_data)\n",
    "\n",
    "# 4. 增量更新\n",
    "if 'last_update' not in st.session_state:\n",
    "    st.session_state.last_update = datetime.now()\n",
    "    st.session_state.data = load_full_data()\n",
    "else:\n",
    "    # 只加载增量数据\n",
    "    new_data = load_incremental_data(st.session_state.last_update)\n",
    "    st.session_state.data = pd.concat([st.session_state.data, new_data])\n",
    "    st.session_state.last_update = datetime.now()\n",
    "'''\n",
    "\n",
    "print(\"⚡ 性能优化核心原则:\")\n",
    "print(\"  1. 尽可能使用缓存\")\n",
    "print(\"  2. 减少数据传输量\")\n",
    "print(\"  3. 延迟加载非关键内容\")\n",
    "print(\"  4. 聚合优先于明细\")\n",
    "print(\"  5. 使用增量更新而非全量刷新\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5.3 用户体验优化\n",
    "\n",
    "**加载状态提示**:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ux_tips = '''\n",
    "# 1. 使用进度条\n",
    "import time\n",
    "\n",
    "progress_bar = st.progress(0)\n",
    "status_text = st.empty()\n",
    "\n",
    "for i in range(100):\n",
    "    progress_bar.progress(i + 1)\n",
    "    status_text.text(f'正在加载数据... {i+1}%')\n",
    "    time.sleep(0.01)\n",
    "\n",
    "status_text.text('加载完成!')\n",
    "\n",
    "# 2. 使用spinner\n",
    "with st.spinner('正在处理数据,请稍候...'):\n",
    "    # 耗时操作\n",
    "    result = complex_calculation()\n",
    "\n",
    "st.success('处理完成!')\n",
    "\n",
    "# 3. 空状态提示\n",
    "if len(filtered_data) == 0:\n",
    "    st.warning('没有符合条件的数据,请调整筛选条件')\n",
    "else:\n",
    "    st.plotly_chart(create_chart(filtered_data))\n",
    "\n",
    "# 4. 错误友好提示\n",
    "try:\n",
    "    data = load_data()\n",
    "except FileNotFoundError:\n",
    "    st.error('数据文件不存在,请先上传数据')\n",
    "    uploaded_file = st.file_uploader(\"上传数据文件\")\n",
    "except Exception as e:\n",
    "    st.error(f'发生错误: {str(e)}')\n",
    "    st.info('请联系技术支持')\n",
    "\n",
    "# 5. 操作反馈\n",
    "if st.button('导出报表'):\n",
    "    with st.spinner('正在生成报表...'):\n",
    "        export_report()\n",
    "    st.success('✅ 报表导出成功!')\n",
    "    st.balloons()  # 庆祝动画\n",
    "'''\n",
    "\n",
    "print(\"🎨 用户体验优化要点:\")\n",
    "print(\"  ✓ 提供清晰的加载状态\")\n",
    "print(\"  ✓ 空状态友好提示\")\n",
    "print(\"  ✓ 错误信息人性化\")\n",
    "print(\"  ✓ 操作即时反馈\")\n",
    "print(\"  ✓ 合理使用动画效果\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## 📝 综合项目作业\n",
    "\n",
    "### 项目: 电商数据分析平台 (⭐⭐⭐⭐⭐)\n",
    "\n",
    "**项目背景**:\n",
    "\n",
    "某电商平台需要一个综合数据分析系统,帮助运营团队、产品团队、市场团队进行数据驱动决策。\n",
    "\n",
    "**功能要求**:\n",
    "\n",
    "**模块1: 运营监控仪表板 (必做)**\n",
    "- [ ] 核心KPI监控(GMV、订单量、用户数、转化率)\n",
    "- [ ] 实时销售趋势图\n",
    "- [ ] 分渠道/品类/地区的多维度分析\n",
    "- [ ] 异常预警功能(销售额骤降、库存告急等)\n",
    "\n",
    "**模块2: 用户分析系统 (必做)**\n",
    "- [ ] RFM客户分层分析\n",
    "- [ ] 用户画像可视化(年龄、性别、地域分布)\n",
    "- [ ] 用户生命周期分析\n",
    "- [ ] 复购率/留存率分析\n",
    "\n",
    "**模块3: 商品分析模块 (必做)**\n",
    "- [ ] 热销商品TOP榜\n",
    "- [ ] 商品类目销售占比\n",
    "- [ ] 库存周转率分析\n",
    "- [ ] 滞销商品预警\n",
    "\n",
    "**模块4: 营销分析模块 (选做)**\n",
    "- [ ] 促销活动效果分析\n",
    "- [ ] 优惠券使用分析\n",
    "- [ ] ROI计算与可视化\n",
    "- [ ] A/B测试结果展示\n",
    "\n",
    "**模块5: 数据导出与分享 (必做)**\n",
    "- [ ] 支持导出Excel/CSV格式\n",
    "- [ ] 生成PDF报告\n",
    "- [ ] 定时报表邮件发送(选做)\n",
    "\n",
    "**技术要求**:\n",
    "\n",
    "1. **数据要求**\n",
    "   - 至少3个月的模拟数据\n",
    "   - 包含订单、用户、商品、库存等多张表\n",
    "   - 数据量不少于10万条订单记录\n",
    "\n",
    "2. **可视化要求**\n",
    "   - 使用Plotly创建所有图表\n",
    "   - 至少包含10种不同类型的图表\n",
    "   - 所有图表支持交互(悬停、缩放、筛选)\n",
    "\n",
    "3. **性能要求**\n",
    "   - 使用缓存机制优化性能\n",
    "   - 页面加载时间 < 3秒\n",
    "   - 支持大数据量展示(采样/聚合)\n",
    "\n",
    "4. **UI/UX要求**\n",
    "   - 响应式布局(支持PC和移动端)\n",
    "   - 统一的色彩主题\n",
    "   - 清晰的导航结构\n",
    "   - 友好的错误提示\n",
    "\n",
    "5. **代码质量**\n",
    "   - 函数模块化,代码复用率高\n",
    "   - 完善的注释和文档字符串\n",
    "   - 遵循PEP 8编码规范\n",
    "\n",
    "**提交内容**:\n",
    "\n",
    "1. 完整的Python代码文件\n",
    "2. 数据文件或数据生成脚本\n",
    "3. README.md(项目说明、安装步骤、使用指南)\n",
    "4. requirements.txt(依赖库列表)\n",
    "5. 截图或录屏展示(可选)\n",
    "\n",
    "**评分标准** (100分):\n",
    "\n",
    "| 评分项 | 分值 | 说明 |\n",
    "|-------|------|------|\n",
    "| 功能完整性 | 30分 | 必做模块全部实现 |\n",
    "| 可视化质量 | 25分 | 图表美观、交互流畅 |\n",
    "| 数据分析深度 | 20分 | 有洞察、有建议 |\n",
    "| 代码质量 | 15分 | 结构清晰、注释完善 |\n",
    "| UI/UX设计 | 10分 | 界面美观、操作便捷 |\n",
    "| 加分项 | +20分 | 选做模块、创新功能 |\n",
    "\n",
    "**提示**:\n",
    "- 参考课件中的企业仪表板代码作为起点\n",
    "- 可以使用真实电商数据集(如Kaggle)\n",
    "- 推荐部署到Streamlit Cloud展示\n",
    "\n",
    "---\n",
    "\n",
    "## 🎓 本讲总结\n",
    "\n",
    "通过本讲学习,你应该掌握:\n",
    "\n",
    "✅ 企业级仪表板的完整开发流程  \n",
    "✅ 数据故事讲述的技巧  \n",
    "✅ 多维度数据分析方法  \n",
    "✅ RFM客户价值分析  \n",
    "✅ 仪表板性能优化  \n",
    "✅ 用户体验设计最佳实践  \n",
    "\n",
    "**🎉 恭喜你完成第5阶段全部课程!**\n",
    "\n",
    "你已经具备了:\n",
    "- 📊 熟练的数据可视化能力\n",
    "- 🎨 优秀的图表设计品味\n",
    "- 💻 完整的仪表板开发技能\n",
    "- 📈 数据驱动决策的思维\n",
    "\n",
    "**下一步建议**:\n",
    "1. 完成综合项目作业\n",
    "2. 部署到云端并分享\n",
    "3. 为开源项目贡献可视化组件\n",
    "4. 学习更高级的可视化框架(Dash、Bokeh)\n",
    "\n",
    "---\n",
    "\n",
    "## 📚 扩展资源\n",
    "\n",
    "### 推荐阅读\n",
    "- 《Storytelling with Data》(用数据讲故事)\n",
    "- 《Information Dashboard Design》(仪表板设计)\n",
    "\n",
    "### 在线资源\n",
    "- Streamlit Gallery: https://streamlit.io/gallery\n",
    "- Plotly Examples: https://plotly.com/python/\n",
    "- Dashboard Design Patterns: https://www.dashboarddesignpatterns.com/\n",
    "\n",
    "### 数据集资源\n",
    "- Kaggle Datasets: https://www.kaggle.com/datasets\n",
    "- UCI Machine Learning Repository: https://archive.ics.uci.edu/ml/\n",
    "\n",
    "---"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.9.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}